package com.demo.spring.security.util;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Accessors(chain = true)
public class Result<T> {
    public final static String CODE_SUCCESS = "SUCCESS";
    public final static String CODE_FAILURE = "FAILURE";

    @Getter@Setter
    private String code = CODE_SUCCESS;
    @Getter@Setter
    private String message = "";
    @Getter@Setter
    private String description;
    @Getter@Setter
    private T record = null;
    @Getter
    private JSONObject page = null;
    @Getter@Setter
    Exception exception;

    protected Result(String code){
        this.code = code;
        this.message = CODE_SUCCESS.equals(code)?"操作成功":"操作失败";
    }

    public static<T> Result<T> FROM(String code){
        return new Result<T>(code);
    }

    public static<T> Result<T> FROM(boolean isSuccess){
        return FROM(isSuccess?CODE_SUCCESS:CODE_FAILURE);
    }

    public static<T> Result<T> SUCCESS(){
        return new Result<T>(CODE_SUCCESS);
    }

    public static<T> Result<T> SUCCESS(T record){
        return new Result<T>(CODE_SUCCESS).setRecord(record);
    }

    public static<T> Result<T> SUCCESS(T record,String message){
        return new Result<T>(CODE_SUCCESS).setRecord(record).setMessage(message);
    }

    public static<T> Result<T> FAILURE(){
        return new Result<T>(CODE_FAILURE);
    }

    public static<T> Result<T> FAILURE(String message){
        return new Result<T>(CODE_FAILURE).setMessage(message);
    }

    public Result<T> toSuccess(){
        this.setCode(CODE_SUCCESS);
        return this;
    }

    public Result<T> toFailure(){
        this.setCode(CODE_SUCCESS);
        return this;
    }

    public boolean isSuccess(){
        return CODE_SUCCESS.equals(this.code);
    }

    public boolean hasRecord(){
        return isSuccess()&&this.record !=null;
    }

    @Override
    public String toString(){
        return JSONUtil.toJsonStr(this);
    }

    public JSONObject toJSONObject(){
        JSONObject result = new JSONObject(this,false);
        result.set("success",CODE_SUCCESS.equals(this.code));
        return result;
    }

    public Result<T> setPage(long current,long size,long total){
        this.page = new JSONObject().set("current",current).set("pageSize",size).set("total",total);
        return this;
    }

}
